﻿namespace NMortgage.UI.Tests
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    using NMortgage.UI.Model;

    [TestClass]
    public class InterestParametersTest
    {
        #region Fields

        private TestContext testContextInstance;

        #endregion Fields

        #region Properties

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #endregion Properties

        #region Methods

        public static IInterestRate GetInvalidParameter0()
        {
            return new InterestParameter() { DistributionType = DistributionType.FixedRate, Months = 0, Years = 0 };
        }

        public static IInterestRate GetParameter0()
        {
            return new InterestParameter() { DistributionType = DistributionType.FixedRate, Months = 1, Years = 1 };
        }

        public static IInterestRate GetParameter1()
        {
            return new InterestParameter() { DistributionType = DistributionType.FixedRate, Months = 2, Years = 2 };
        }

        public static IInterestRate GetParameter2()
        {
            return new InterestParameter() { DistributionType = DistributionType.FixedRate, Months = 3, Years = 3 };
        }

        [TestMethod]
        public void Add()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter = GetParameter0();
            target.Add(parameter);
            bool foundRef = false;
            foreach (var p in target)
            {
                if (p == parameter) { foundRef = true; break; }
            }

            Assert.IsTrue(foundRef);
        }

        [TestMethod]
        public void Add_More_Than_One_Of_Same_Type()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter0();
            target.Add(parameter0);
            target.Add(parameter1);

            int actual = target.Count;
            int expected = 2;

            Assert.AreEqual<int>(expected, actual);
        }

        [TestMethod]
        public void Add_Only_Once()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter = GetParameter0();
            target.Add(parameter);
            target.Add(parameter);

            int actual = target.Count;
            int expected = 1;

            Assert.AreEqual<int>(expected, actual);
        }

        [TestMethod]
        public void Can_Move_Down_from_Last()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter1();

            target.Add(parameter0);
            target.Add(parameter1);

            bool expected = false;
            bool actual;
            actual = target.CanMoveDown(parameter1);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Can_Move_Down_from_Middle()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter1();
            IInterestRate parameter2 = GetParameter2();

            target.Add(parameter0);
            target.Add(parameter1);
            target.Add(parameter2);

            bool expected = true;
            bool actual;
            actual = target.CanMoveDown(parameter1);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Can_Move_Down_from_Only()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();

            target.Add(parameter0);

            bool expected = false;
            bool actual;
            actual = target.CanMoveDown(parameter0);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Can_Move_Many_from_Times()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            int expected = 0;
            int actual = 0;

            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter1();
            IInterestRate parameter2 = GetParameter2();

            target.Add(parameter0);
            target.Add(parameter1);
            target.Add(parameter2);

            target.MoveDown(parameter0);
            expected = 1;
            actual = target.IndexOf(parameter0);
            Assert.AreEqual(expected, actual);

            target.MoveDown(parameter0);
            expected = 2;
            actual = target.IndexOf(parameter0);
            Assert.AreEqual(expected, actual);

            target.MoveDown(parameter0);
            expected = 2;
            actual = target.IndexOf(parameter0);
            Assert.AreEqual(expected, actual);

            target.MoveDown(parameter2);
            expected = 2;
            actual = target.IndexOf(parameter2);
            Assert.AreEqual(expected, actual);

            expected = 1;
            actual = target.IndexOf(parameter0);
            Assert.AreEqual(expected, actual);

            target.MoveDown(parameter1);
            expected = 1;
            actual = target.IndexOf(parameter1);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Can_Move_Up_from_Last()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter1();

            target.Add(parameter0);
            target.Add(parameter1);

            bool expected = false;
            bool actual;
            actual = target.CanMoveUp(parameter0);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Can_Move_Up_from_Middle()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter1();
            IInterestRate parameter2 = GetParameter2();

            target.Add(parameter0);
            target.Add(parameter1);
            target.Add(parameter2);

            bool expected = true;
            bool actual;
            actual = target.CanMoveUp(parameter1);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Can_Move_Up_from_Only()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();

            target.Add(parameter0);

            bool expected = false;
            bool actual;
            actual = target.CanMoveUp(parameter0);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Can_Not_Move_Top_One_Up()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();

            target.Add(parameter0);
            target.MoveUp(parameter0);

            int expected = 0;
            int actual = target.IndexOf(parameter0);
            Assert.AreEqual(expected, actual);
        }


        [TestMethod]
        public void IndexOf0()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter1();

            target.Add(parameter0);
            target.Add(parameter1);

            int expected = 0;
            int actual = target.IndexOf(parameter0);
            Assert.AreEqual<int>(expected, actual);
        }

        [TestMethod]
        public void IndexOf1()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter1();

            target.Add(parameter0);
            target.Add(parameter1);

            int expected = 1;
            int actual = target.IndexOf(parameter1);
            Assert.AreEqual<int>(expected, actual);
        }

        [TestMethod]
        public void InterestParametersConstructor()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            Assert.IsNotNull(target);
        }

        [TestMethod]
        public void Move_Down_First()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter1();

            target.Add(parameter0);
            target.Add(parameter1);

            int initialIndex = target.IndexOf(parameter0);

            target.MoveDown(parameter0);

            int expected = initialIndex + 1;
            int actual = target.IndexOf(parameter0);
            Assert.AreEqual<int>(expected, actual);
        }

        [TestMethod]
        public void Move_Down_Last()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter1();

            target.Add(parameter0);
            target.Add(parameter1);

            int expected = 1;
            int actual = target.IndexOf(parameter1);
            Assert.AreEqual<int>(expected, actual);
        }

        [TestMethod]
        public void Move_Up_First()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter1();

            target.Add(parameter0);
            target.Add(parameter1);

            int expected = 0;
            int actual = target.IndexOf(parameter0);
            Assert.AreEqual<int>(expected, actual);
        }

        [TestMethod]
        public void Move_Up_Last()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter1();

            target.Add(parameter0);
            target.Add(parameter1);

            target.MoveUp(parameter1);

            int expected = 0;
            int actual = target.IndexOf(parameter1);
            Assert.AreEqual<int>(expected, actual);
        }

        [TestMethod]
        public void Remove()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter = GetParameter0();
            target.Add(parameter);
            target.Remove(parameter);
            bool foundRef = false;
            foreach (var p in target)
            {
                if (p == parameter) { foundRef = true; break; }
            }

            Assert.IsFalse(foundRef);
        }

        [TestMethod]
        public void TotalMonths()
        {
            InterestParameterCollection target = new InterestParameterCollection();
            IInterestRate parameter0 = GetParameter0();
            IInterestRate parameter1 = GetParameter1();
            IInterestRate parameter2 = GetParameter2();

            target.Add(parameter0);
            target.Add(parameter1);
            target.Add(parameter2);

            int expected = parameter0.TotalDurationInMonths + parameter1.TotalDurationInMonths + parameter2.TotalDurationInMonths;
            int actual = target.TotalMonths;
            Assert.AreEqual<int>(expected, actual);
        }

        #endregion Methods
    }
}